package com.jdy.haoduoai.view.swipemenu;

import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.widget.ScrollerCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.AbsListView;
import android.widget.FrameLayout;

import com.ycsj.goldmedalnewconcept.R;

//import com.jdy.haoduoai.R;

/**
 * 
 * @author baoyz
 * @date 2014-8-23
 * 
 */
public class SwipeMenuLayout extends FrameLayout {

  private static final int CONTENT_VIEW_ID = 1;
  private static final int MENU_VIEW_ID = 2;

  private static final int STATE_CLOSE = 0;
  private static final int STATE_OPEN = 1;

  private View mContentView;
  private SwipeMenuView mMenuView;
  private int mDownX;
  private int state = STATE_CLOSE;
  private GestureDetectorCompat mGestureDetector;
  private OnGestureListener mGestureListener;
  private boolean isFling;
  private final int MIN_FLING = dp2px(15);
  private final int MAX_VELOCITYX = -dp2px(500);
  private ScrollerCompat mOpenScroller;
  private ScrollerCompat mCloseScroller;
  private int mBaseX;
  private int position;
  public boolean bHideMore;
  private Interpolator mCloseInterpolator;
  private Interpolator mOpenInterpolator;

  public SwipeMenuLayout(View contentView, SwipeMenuView menuView) {
    this(contentView, menuView, null, null);
  }

  public SwipeMenuLayout(View contentView, SwipeMenuView menuView,
      Interpolator closeInterpolator, Interpolator openInterpolator) {
    super(contentView.getContext());
    mCloseInterpolator = closeInterpolator;
    mOpenInterpolator = openInterpolator;
    mContentView = contentView;
    mMenuView = menuView;
    mMenuView.setLayout(this);
    init();
  }

  // private SwipeMenuLayout(Context context, AttributeSet attrs, int
  // defStyle) {
  // super(context, attrs, defStyle);
  // }

  private SwipeMenuLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  private SwipeMenuLayout(Context context) {
    super(context);
  }

  public int getPosition() {
    return position;
  }

  public void setPosition(int position) {
    this.position = position;
    mMenuView.setPosition(position);
  }

  @SuppressLint("ResourceType")
  private void init() {
    setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.WRAP_CONTENT));
    mGestureListener = new SimpleOnGestureListener() {
      @Override
      public boolean onDown(MotionEvent e) {
        isFling = false;
        return true;
      }

      @Override
      public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
          float velocityY) {
        // TODO
        if ((e1.getX() - e2.getX()) > MIN_FLING && velocityX < MAX_VELOCITYX) {
          isFling = true;
        }
        // Log.i("byz", MAX_VELOCITYX + ", velocityX = " + velocityX);
        return super.onFling(e1, e2, velocityX, velocityY);
      }
    };
    mGestureDetector = new GestureDetectorCompat(getContext(), mGestureListener);

    // mScroller = ScrollerCompat.create(getContext(), new
    // BounceInterpolator());
    if (mCloseInterpolator != null) {
      mCloseScroller = ScrollerCompat.create(getContext(), mCloseInterpolator);
    } else {
      mCloseScroller = ScrollerCompat.create(getContext());
    }
    if (mOpenInterpolator != null) {
      mOpenScroller = ScrollerCompat.create(getContext(), mOpenInterpolator);
    } else {
      mOpenScroller = ScrollerCompat.create(getContext());
    }

    LayoutParams contentParams = new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.WRAP_CONTENT);
    mContentView.setLayoutParams(contentParams);
    if (mContentView.getId() < 1) {
      mContentView.setId(CONTENT_VIEW_ID);
    }

    mMenuView.setId(MENU_VIEW_ID);
    mMenuView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
        LayoutParams.WRAP_CONTENT));

    addView(mContentView);
    addView(mMenuView);

    // if (mContentView.getBackground() == null) {
    // mContentView.setBackgroundColor(Color.WHITE);
    // }

    // in android 2.x, MenuView height is MATCH_PARENT is not work.
    // getViewTreeObserver().addOnGlobalLayoutListener(
    // new OnGlobalLayoutListener() {
    // @Override
    // public void onGlobalLayout() {
    // setMenuHeight(mContentView.getHeight());
    // // getViewTreeObserver()
    // // .removeGlobalOnLayoutListener(this);
    // }
    // });

  }

  @Override
  protected void onAttachedToWindow() {
    super.onAttachedToWindow();
  }

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
  }

  public boolean onSwipe(MotionEvent event) {
    mGestureDetector.onTouchEvent(event);
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
      mDownX = (int) event.getX();
      isFling = false;
      break;
    case MotionEvent.ACTION_MOVE:
      // Log.i("byz", "downX = " + mDownX + ", moveX = " + event.getX());
      int dis = (int) (mDownX - event.getX());
      if (state == STATE_OPEN) {
        dis += mMenuView.getWidth();
      }
      swipe(dis);
      break;
    case MotionEvent.ACTION_UP:
      if (isFling || (mDownX - event.getX()) > (mMenuView.getWidth() / 2)) {
        // open
        smoothOpenMenu(bHideMore);
      } else {
        // close
        smoothCloseMenu(bHideMore);
        return false;
      }
      break;
    }
    return true;
  }

  public boolean isOpen() {
    return state == STATE_OPEN;
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    return super.onTouchEvent(event);
  }

  private void swipe(int dis) {
    if (dis > mMenuView.getWidth()) {
      dis = mMenuView.getWidth();
    }
    if (dis < 0) {
      dis = 0;
    }
    mContentView.layout(-dis, mContentView.getTop(), mContentView.getWidth()
        - dis, getMeasuredHeight());
    mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(),
        mContentView.getWidth() + mMenuView.getWidth() - dis,
        mMenuView.getBottom());
  }

  @Override
  public void computeScroll() {
    if (state == STATE_OPEN) {
      if (mOpenScroller.computeScrollOffset()) {
        swipe(mOpenScroller.getCurrX());
        postInvalidate();
      }
    } else {
      if (mCloseScroller.computeScrollOffset()) {
        swipe(mBaseX - mCloseScroller.getCurrX());
        postInvalidate();
      }
    }
  }

  public void smoothCloseMenu(boolean hideMore) {
    state = STATE_CLOSE;
    mBaseX = -mContentView.getLeft();
    mCloseScroller.startScroll(0, 0, mBaseX, 0, 350);

    if (!hideMore) {
      View more = mContentView.findViewById(R.id.more_layout);
      if (more != null)
        more.setVisibility(View.VISIBLE);
    }

    postInvalidate();
  }

  public void smoothOpenMenu(boolean hideMore) {
    state = STATE_OPEN;
    mOpenScroller.startScroll(-mContentView.getLeft(), 0, mMenuView.getWidth(),
        0, 350);

    if (!hideMore) {
      View more = mContentView.findViewById(R.id.more_layout);
      more.setVisibility(View.GONE);
    }

    postInvalidate();
  }

  public void closeMenu() {
    if (mCloseScroller.computeScrollOffset()) {
      mCloseScroller.abortAnimation();
    }
    if (state == STATE_OPEN) {
      state = STATE_CLOSE;
      swipe(0);
    }
  }

  // public void openMenu() {
  // if (state == STATE_CLOSE) {
  // state = STATE_OPEN;
  // swipe(mMenuView.getWidth());
  // }
  // }

  public View getContentView() {
    return mContentView;
  }

  public SwipeMenuView getMenuView() {
    return mMenuView;
  }

  private int dp2px(int dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
        getContext().getResources().getDisplayMetrics());
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    mMenuView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
        MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    mContentView.layout(0, 0, getMeasuredWidth(),
        mContentView.getMeasuredHeight());
    mMenuView.layout(getMeasuredWidth(), 0,
        getMeasuredWidth() + mMenuView.getMeasuredWidth(),
        mContentView.getMeasuredHeight());
    // setMenuHeight(mContentView.getMeasuredHeight());
    // bringChildToFront(mContentView);
  }

  public void setMenuHeight(int measuredHeight) {
    Log.i("byz", "pos = " + position + ", height = " + measuredHeight);
    LayoutParams params = (LayoutParams) mMenuView.getLayoutParams();
    if (params.height != measuredHeight) {
      params.height = measuredHeight;
      mMenuView.setLayoutParams(mMenuView.getLayoutParams());
    }
  }
}